"""
元类和类的关系，就相当于类和实例的关系。
所以在__call__方法中，元类传入的参数是cls(类)，
类传入的参数是self(对象/实例本身)

"""
import hashlib
from tornado.log import app_log

class Singleton(type):
    # 函数是对象，函数是可调用的对象。
    # __call___把类的实例变成一个可调用的对象
    def __call__(cls, *args, **kwargs):
        # 判断度对象是不是实例？
        if hasattr(cls, "_instance"):
            return cls._instance
        else:
            # 不是实例，就创建实例！
            cls._instance = super(Singleton, cls).__call__(*args, **kwargs)

"""
python中的any, all函数？
any（）函数传入的参数全为假，返回true, 否则返回false.
all()函数的参数全为真，返回true, 否则返回false.
"""
import asyncio
from functools import wraps
"""缓存"""
# 装饰类的方法
def cached(timeout=5, key='{}'):
    def cache_to_memcached(func):
        @wraps(func)
        async def decorators(self, *args, **kwargs):
            # 创建cache_key，装饰的类的名字和方法的名字
            key_str = self.__class__.__name__.lower() + ":"+ func.__name__ + ':'
            if args:
                # 使用md5生成 摘要
                key_str += hashlib.md5(str(*args)).hexdigest()
            if kwargs:
                key_str += hashlib.md5(str(kwargs)).hexdigest()
            cache_key = key.format(key_str)
            # 在这里连接上下文）
            with StoreCache() as mc:
                cache_value = mc.get(cache_key)
            if  cache_value is not None:
                app_log.info.debug('')
                return cache_value
            cache_value = await func(self, *args, **kwargs)
            with StoreCache() as mc:
                mc.set(cache_key, cacge_value, timeout)
            return cache_value
        return decorators
    return cache_to_memcached














